package demo01;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 *  写入数据的原理（内存 --> 硬盘）：
 *      java程序 --> JVM（java虚拟机） --> OS（操作系统） --> OS调用写数据的方法 --> 把数据写入到文件中
 * 
 *  FileOutputStream类的构造方法：
 *      FileOutputStream(File file)：创建文件字节输出流，用于写入字节到指定的File对象
 *      FileOutputStream(String name)：创建文件字节输出流，用于写入字节到路径字符串指定的文件
 *      FileOutputStream(File file, boolean append)：创建文件字节输出流，用于写入字节到指定的File对象，指定是否追加写
 *      FileOutputStream(String name, boolean append)：创建文件字节输出流，用于写入字节到路径字符串指定的文件，指定是否追加写
 * 
 *  FileOutputStream类的常用方法：
 *      public void close()：关闭文件字节输出流，释放资源
 *      public void write(int b)：写入一个字节，将参数字节写入文件
 *      public void write(byte[] b)：写入字节数组，将一组字节写入到文件
 *      public void write(byte[] b, int off, int len)：写入指定长度的字节数组，将一个字节数组中从off索引开始的len个字节写入到文件
 * 
 *  文件字节输出流的使用步骤：
 *      1. 创建一个FileOutputStream对象，构造方法中传递写入数据的目的地路径
 *      2. 调用FileOutputStream对象的方法write，将数据写入到文件中
 *      3. 关闭文件字节输出流，释放资源（流使用会占用内存，使用完毕需要清空内存，提高程序效率）
 */
public class Demo01FileOutputStream {
    public static void main(String[] args) throws IOException { // 以下方法会抛出异常，可以进行声明处理
        /*
         *  FileOutputStream构造方法执行了以下几件事：
         *      1. 创建了一个文件字节输出流对象fileOutputStreamA
         *      2. 根据构造参数的路径创建了一个空文件"a.txt"，路径可以是文件类型，也可以是路径名的字符串
         *      3. 把fileOutputStreamA指向创建好的文件"a.txt"
         *      4. 如果参数列表没有填入append参数，或是填入append参数为false，则代表清空原有数据并从头开始写
         *         如果参数列表填入append参数为true，则代表追加写
         *  FileOutputStream构造方法会抛出FileNotFoundException文件拒绝访问异常，可以声明处理
         *  写入方法会抛出IOException，是FileNotFoundException的父类，可以通过直接让方法声明IO异常来完成处理
         */
        FileOutputStream fileOutputStreamA = new FileOutputStream(new File("file\\a.txt"));
        FileOutputStream fileOutputStreamB = new FileOutputStream("file\\b.txt", true);

        /*
         *  write()方法可以填入三种参数：
         *      1. int b ：代表输出单个字节
         *      2. byte[] b ：代表输出字节数组
         *      3. byte[] b, int off, int len ：代表输出字节数组从第off个字节开始的len个字节
         *  如果需要获得一个字符串对应的字节数组，可以让这个字符串调用getBytes()方法即可
         *  如果需要输出换行符，Windows操作系统下"\r\n"代表换行符，用"\r\n"调用getBytes()方法即可
         *  write方法会抛出IOExceptionIO异常，可以声明处理
         */
        fileOutputStreamA.write(98); // a.txt文件显示：b
        for (Byte b : "TOASTIE".getBytes()) {
            fileOutputStreamB.write(b);
            fileOutputStreamB.write("\r\n".getBytes()); // 输出换行符
        }
        fileOutputStreamB.write("TOOHOO".getBytes(), 2, 3);
        /*
         *  b.txt文件显示：
         *      T
         *      O
         *      A
         *      S
         *      T
         *      I
         *      E
         *      OHO
         */

        /*
         *  文件字节输出流使用完毕后需要使用close()方法关闭文件，释放资源
         *  close方法会抛出IOExceptionIO异常，可以声明处理
         */
        fileOutputStreamA.close();
        fileOutputStreamB.close();
    }
}
